package com.scheduling.schedule.controller;

import com.scheduling.common.result.Result;
import com.scheduling.schedule.dto.SchedulePlanDTO;
import com.scheduling.schedule.dto.ScheduleRequest;
import com.scheduling.schedule.dto.ScheduleResult;
import com.scheduling.schedule.entity.SchedulePlan;
import com.scheduling.schedule.entity.WorkOrder;
import com.scheduling.schedule.service.ScheduleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 排产控制器
 *
 * @author 开发团队
 */
@Slf4j
@RestController
@RequestMapping("/api/schedule")
@RequiredArgsConstructor
@Tag(name = "排产管理", description = "智能排产算法相关接口")
public class
ScheduleController {

    private final ScheduleService scheduleService;

    /**
     * 执行排产算法
     */
    @PostMapping("/execute")
    @Operation(summary = "执行排产算法", description = "根据选择的算法对工单进行智能排产")
    public Result<ScheduleResult> executeSchedule(@Validated @RequestBody ScheduleRequest request) {
        log.info("执行排产算法接口调用，算法类型: {}, 订单数量: {}", request.getAlgorithmType(), request.getOrderIds().size());

        try {
            ScheduleResult result = scheduleService.executeSchedule(request);

            if (result.isSuccess()) {
                return Result.success(result, "排产算法执行成功");
            } else {
                return Result.error(result.getErrorMessage());
            }

        } catch (Exception e) {
            log.error("执行排产算法失败", e);
            return Result.error("排产算法执行失败: " + e.getMessage());
        }
    }

    /**
     * 保存排产计划
     */
    @PostMapping("/save")
    @Operation(summary = "保存排产计划", description = "将排产结果保存为正式的排产计划")
    public Result<String> saveSchedulePlan(@RequestBody ScheduleRequest request) {
        log.info("保存排产计划接口调用，计划名称: {}", request.getPlanName());

        try {
            // 先执行排产算法
            ScheduleResult scheduleResult = scheduleService.executeSchedule(request);

            if (!scheduleResult.isSuccess()) {
                return Result.error("排产算法执行失败: " + scheduleResult.getErrorMessage());
            }

            // 保存排产计划
            String planId = scheduleService.saveSchedulePlan(scheduleResult, request);

            return Result.success(planId, "排产计划保存成功");

        } catch (Exception e) {
            log.error("保存排产计划失败", e);
            return Result.error("保存排产计划失败: " + e.getMessage());
        }
    }

    /**
     * 确认排产计划
     */
    @PutMapping("/confirm/{planId}")
    @Operation(summary = "确认排产计划", description = "确认并激活排产计划")
    public Result<Void> confirmSchedulePlan(
            @Parameter(description = "排产计划ID") @PathVariable String planId) {
        log.info("确认排产计划接口调用，计划ID: {}", planId);

        try {
            boolean success = scheduleService.confirmSchedulePlan(planId);

            if (success) {
                return Result.success(null, "排产计划确认成功");
            } else {
                return Result.error("排产计划确认失败");
            }

        } catch (Exception e) {
            log.error("确认排产计划失败，计划ID: {}", planId, e);
            return Result.error("确认排产计划失败: " + e.getMessage());
        }
    }

    /**
     * 查询排产计划列表
     */
    @GetMapping("/plans")
    @Operation(summary = "查询排产计划列表", description = "分页查询所有排产计划")
    public Result<List<SchedulePlan>> getSchedulePlans() {
        log.info("查询排产计划列表接口调用");

        try {
            List<SchedulePlan> schedulePlans = scheduleService.getSchedulePlans();
            return Result.success(schedulePlans, "查询排产计划列表成功");

        } catch (Exception e) {
            log.error("查询排产计划列表失败", e);
            return Result.error("查询排产计划列表失败: " + e.getMessage());
        }
    }

    /**
     * 查询排产计划详情
     */
    @GetMapping("/plans/{planId}")
    @Operation(summary = "查询排产计划详情", description = "根据ID查询排产计划的详细信息")
    public Result<SchedulePlanDTO> getSchedulePlanById(
            @Parameter(description = "排产计划ID") @PathVariable String planId) {
        log.info("查询排产计划详情接口调用，计划ID: {}", planId);

        try {
            SchedulePlanDTO schedulePlanDTO = scheduleService.getSchedulePlanById(planId);

            if (schedulePlanDTO != null) {
                return Result.success(schedulePlanDTO, "查询排产计划详情成功");
            } else {
                return Result.error("排产计划不存在");
            }

        } catch (Exception e) {
            log.error("查询排产计划详情失败，计划ID: {}", planId, e);
            return Result.error("查询排产计划详情失败: " + e.getMessage());
        }
    }

    /**
     * 删除排产计划
     */
    @DeleteMapping("/plans/{planId}")
    @Operation(summary = "删除排产计划", description = "删除指定的排产计划")
    public Result<Void> deleteSchedulePlan(
            @Parameter(description = "排产计划ID") @PathVariable String planId) {
        log.info("删除排产计划接口调用，计划ID: {}", planId);

        try {
            boolean success = scheduleService.deleteSchedulePlan(planId);

            if (success) {
                return Result.success(null, "排产计划删除成功");
            } else {
                return Result.error("排产计划删除失败");
            }

        } catch (Exception e) {
            log.error("删除排产计划失败，计划ID: {}", planId, e);
            return Result.error("删除排产计划失败: " + e.getMessage());
        }
    }

    /**
     * 查询待排产工单
     */
    @GetMapping("/pending-orders")
    @Operation(summary = "查询待排产工单", description = "获取所有待排产的工单列表")
    public Result<List<WorkOrder>> getPendingWorkOrders() {
        log.info("查询待排产工单接口调用");

        try {
            List<WorkOrder> workOrders = scheduleService.getPendingWorkOrders();
            return Result.success(workOrders, "查询待排产工单成功");

        } catch (Exception e) {
            log.error("查询待排产工单失败", e);
            return Result.error("查询待排产工单失败: " + e.getMessage());
        }
    }

    /**
     * 获取支持的排产算法
     */
    @GetMapping("/algorithms")
    @Operation(summary = "获取支持的排产算法", description = "获取系统支持的所有排产算法类型")
    public Result<List<String>> getSupportedAlgorithms() {
        log.info("获取支持的排产算法接口调用");

        try {
            List<String> algorithms = scheduleService.getSupportedAlgorithmTypes();
            return Result.success(algorithms, "获取排产算法列表成功");

        } catch (Exception e) {
            log.error("获取支持的排产算法失败", e);
            return Result.error("获取排产算法列表失败: " + e.getMessage());
        }
    }
} 